package com.dx.mes.service.spc.service;

import com.dx.common.table.ppt.Bis_data;
import com.dx.common.table.ppt.Bis_m_item;
import com.dx.mes.common.dao.IBisDataDao;
import com.dx.mes.common.dao.IBisMItemDao;
import com.dx.mes.common.transcoder.util.AppContext;
import com.dx.mes.common.transcoder.util.JacksonUtil;
import com.dx.mes.common.transcoder.util.LogUtils;
import com.dx.mes.common.transcoder.util.MqOpe;
import com.dx.mes.service.spc.tx.XpcAnalysis.XpcAnalysisI;
import com.dx.mes.service.spc.tx.XpcAnalysis.XpcAnalysisIA;
import com.dx.mes.service.spc.tx.XpcAnalysis.XpcAnalysisIB;
import com.dx.mes.service.spc.tx.XpcAnalysis.XpcAnalysisO;
import com.dx.mes.service.spc.tx.Xpcmsdt.XpcmsrdtI;
import com.dx.mes.service.spc.tx.Xpcmsdt.XpcmsrdtIA;
import com.dx.mes.service.spc.tx.Xpcmsdt.XpcmsrdtO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.sql.Timestamp;
import java.util.*;

import static com.dx.mes.common.bean.def.GenericDef.*;

/**
 * Created by XXD on 2018/4/9.
 */
@Service("xpcAnalysisService")
public class XpcAnalysisService implements IXpcAnalysisService {
    private long start = 0;
    private long end = 0;
    private LogUtils logUtils;

    @Autowired
    private IFqprepdataService fqprepdataService;

    @Autowired
    private IBisMItemDao bisMItemDao;

    @Autowired
    private IBisDataDao bisDataDao;

    public String subMainProc(String evt_no, String strInMsg) {
        AppContext.clear();
        AppContext.setCurrServiceName(XpcAnalysisService.class.getSimpleName());
        AppContext.setCurrEventNumber(evt_no);
        logUtils = new LogUtils(XpcAnalysisService.class);
//        logUtils.info("[InTrx:" + strInMsg + "]");

        long lRc = _NORMAL;
        String strOutMsg = null;
        XpcAnalysisI inTrx = new XpcAnalysisI();
        XpcAnalysisO outTrx = new XpcAnalysisO();

        outTrx.setTrx_id(T_FRPUPLPTN);
        outTrx.setType_id(TRX_OUT);

        try {
//            inTrx = (XpcAnalysisI) MqOpe.inStr2Obj(strInMsg, inTrx);
            inTrx = JacksonUtil.fromJson(strInMsg, XpcAnalysisI.class);
            lRc = subMainProc2(inTrx);

            if (lRc == _NORMAL) {
                outTrx.setRtn_code(RETURN_CODE_OK);
            } else {
                outTrx.setRtn_code(String.valueOf(lRc));
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            }
        } catch (Exception ex) {
            outTrx.setRtn_code(RETURN_CODE_UNKNOWN);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        } finally {
            strOutMsg = MqOpe.obj2Str(outTrx);
//            logUtils.info("[OutTrx:" + strOutMsg + "]");
        }
        return strOutMsg;
    }

    public List<Bis_m_item> queryItems(String tool_id_fk, String mes_id_fk) {
        String hql2 = "From Bis_m_item where tool_id_fk = '" + tool_id_fk+"'";
        hql2 += " and mes_id_fk = '" + mes_id_fk +"'";
        hql2 += " order by data_seq";
        List<Bis_m_item> bis_m_items = bisMItemDao.find(hql2);
        return bis_m_items;
    }

    //1.机台报警。 2.制程数据 ，3.spc量测数据
    public List<Bis_data> queryBisData(List<String> datagroup) {
        String str = "";
        for(int i = 0 ;i < datagroup.size()-1;i++){
            str += "'" +datagroup.get(i).toString().trim() +"',";
        }
        str += "'" + datagroup.get(datagroup.size() - 1).toString().trim() +"'";

        String hql = "From Bis_data where data_cate = 'MLGP'";
        if(datagroup.size() > 0){
            hql = hql + " AND data_desc in (" + str +")";
        }
        List<Bis_data> bisDataList= bisDataDao.find(hql);
       return bisDataList;
    }

    public long subMainProc2(XpcAnalysisI inTrx) throws Exception {
        long lRc = _NORMAL;
        String fabId = inTrx.getFab();//厂别
        String line = inTrx.getLine();//线别
        String opeId = inTrx.getOperation();//站点
        String rpt_time = inTrx.getRpt_time();//上报时间
        List<XpcAnalysisIA> iaryList = inTrx.getDataList();
        //设备  数据结构体
        Map<String, List<XpcAnalysisIB>> toolHashMap = new HashMap<String, List<XpcAnalysisIB>>();

        for (int i = 0; i < iaryList.size(); i++) {
            String toolId = iaryList.get(i).getEqt();//主设备
            String subToolId = iaryList.get(i).getSubEqt();//子设备
//            String makeSubToolId = "";
//            if(toolId.equals(subToolId)){
//                makeSubToolId = subToolId;
//            }else{
//                makeSubToolId = toolId +"_"+subToolId;
//            }
            String timestamp = iaryList.get(i).getTimeStamp();//只有数值有变化才会变
            String itemId = iaryList.get(i).getItem_ID();//?
            String dataValueType = iaryList.get(i).getData_Type();//数据类型  double int ...
            String value = iaryList.get(i).getValue();//数据值
            String quality = iaryList.get(i).getQuality();//质量  要存 rawdata，EDC表不存
            String updateCount = iaryList.get(i).getUpdate_Count();//更新次数?
            String variableName = iaryList.get(i).getVariableName();//参数名称

            XpcAnalysisIB dataBody = new XpcAnalysisIB();
            dataBody.setTimestamp(rpt_time);//上报时间，统一
            dataBody.setItemId(itemId);
            dataBody.setDataValueType(dataValueType);
            dataBody.setValue(value);
            dataBody.setQuality(quality);
            dataBody.setUpdateCount(updateCount);
            dataBody.setVariableName(variableName);
            dataBody.setUpdateTimestamp(timestamp);//警报和状态的更新时间
            dataBody.setTool_id_fk(toolId);
            dataBody.setSub_tool_id_fk(subToolId);
            if(toolHashMap.containsKey(subToolId)){
                toolHashMap.get(subToolId).add(dataBody);
            }else{
                List<XpcAnalysisIB> list = new ArrayList<XpcAnalysisIB>();
                list.add(dataBody);
                toolHashMap.put(subToolId,list);
            }
        }


        Iterator iter = toolHashMap.entrySet().iterator();
        while (iter.hasNext()) {
            Map.Entry entry = (Map.Entry) iter.next(); // 把hashmap转成Iterator再迭代到entry
            Object key = entry.getKey(); // 从entry获取key 设备ID
            Object val = entry.getValue(); // 从entry获取value 设备上报的数据集合

            String toolId = (String)key;
            List<XpcAnalysisIB> tooldataList = (ArrayList<XpcAnalysisIB>)val;

            //查询bis_m_item设置的参数列表
            List<Bis_m_item> bisMItemList = queryItems(toolId,"MAPA");
            if(bisMItemList.size() == 0){
                continue;
            }
            //one by one
            XpcmsrdtO xpcmsrdtO = new XpcmsrdtO();
            XpcmsrdtI xpcmsrdtI = newSendTrx(fabId,line,opeId,toolId,tooldataList,bisMItemList);
            xpcmsrdtO = autoReportSPC(xpcmsrdtI);
            if (!xpcmsrdtO.getRtn_code().equals(RETURN_CODE_OK)) {
//               logUtils.error(xpcmsrdtO.getRtn_mesg());
               continue;
            }
        }

        return lRc;
    }

    private XpcmsrdtI newSendTrx(String fabId, String line, String opeId, String toolId, List<XpcAnalysisIB> tooldataList,List<Bis_m_item> bisMItemList) {
        XpcmsrdtI trxI = new XpcmsrdtI();
        trxI.setTool_id(toolId);
        trxI.setFabId(fabId);
        trxI.setLineId(line);
        trxI.setOpe_id(opeId);
        trxI.setRep_unit_fk("P");//上报单元 P:process M:messure
        trxI.setData_pat_fk("00");//上报属性 00,01,02,03   00:EDC

        List<XpcmsrdtIA> iaryList = new ArrayList<XpcmsrdtIA>();
        Integer vlsize = tooldataList.size();//上报的数据的size
        Integer itemsize = bisMItemList.size();//设置的item的size
        for (int m = 0; m < vlsize; m++) {
            if (m >= itemsize) {
                break;
            }
            XpcAnalysisIB data = tooldataList.get(m);
             String dataGroup = data.getVariableName();

            String updateTimestamp = data.getUpdateTimestamp();
            String itemId = data.getItemId();
            String dataValueType = data.getDataValueType();
            String value = data.getValue();
            String quality = data.getQuality();
            String toolIdFk = data.getTool_id_fk();
            String subToolIdFk = data.getSub_tool_id_fk();

                XpcmsrdtIA iary = new XpcmsrdtIA();
                iary.setData_group(bisMItemList.get(m).getData_group());
                iary.setData_value(value);
                iary.setData_quality(quality);
                iary.setData_group_seq(bisMItemList.get(m).getData_group_seq());
                iary.setData_type(bisMItemList.get(m).getData_type());
                iary.setUpdateTimestamp(updateTimestamp);
                iary.setItem_id(itemId);
                iary.setData_value_type(dataValueType);
                iary.setTool_id_fk(toolIdFk);
                iary.setSub_tool_id_fk(subToolIdFk);
                iaryList.add(iary);
        }

        trxI.setMes_id_fk("MAPA");
        trxI.setFlag("A");
        trxI.setData_cnt(String.valueOf(iaryList.size()));
        trxI.setIary(iaryList);
        //TODO
        String timestamp = tooldataList.get(0).getTimestamp();
        trxI.setEvt_timestamp(Timestamp.valueOf(timestamp));//量测时间
        return trxI;
    }

    private XpcmsrdtO autoReportSPC(XpcmsrdtI inTrx) throws Exception {
        XpcmsrdtI xpcmsrdtI = inTrx;
        XpcmsrdtO xpcmsrdtO = new XpcmsrdtO();
        xpcmsrdtO.setTrx_id("FQPEDCDAT");
        xpcmsrdtO.setTrx_id("O");

        String strOutTrx = fqprepdataService.subMainProc(AppContext.getCurrEventNumber(),
                JacksonUtil.toJSONStr(xpcmsrdtI));
        xpcmsrdtO = JacksonUtil.fromJson(strOutTrx, XpcmsrdtO.class);
        return xpcmsrdtO;
    }
}
